﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace Aliyun.MQS.SDK
{
    public interface ICommonHeaderPlugin : IPlugin
    {
        void SetCommonHeader(HttpWebRequest request, string accessKeyID, string accessKeySecret);
    }

    public class DefaultCommonHeaderPlugin : ICommonHeaderPlugin
    {
        void ICommonHeaderPlugin.SetCommonHeader(HttpWebRequest request, string accessKeyID, string accessKeySecret)
        {
            request.Date = DateTime.UtcNow;
            request.Headers.Add("x-mqs-version", "2014-07-08");
            this.SetAuthorization(request, accessKeyID, accessKeySecret);
        }

        protected virtual void SetAuthorization(HttpWebRequest request, string accessKeyID, string accessKeySecret)
        {
            Encoding encoded = PluginManager.Instance.Resolve<IEncodingPlugin>().Encoded;

            //Build the raw data for computing the signature.
            var rawDataBuilder = new StringBuilder();
            rawDataBuilder.Append(request.Method).Append("\n"); //VERB
            rawDataBuilder.Append("\n"); //CONTENT-MD5
            rawDataBuilder.Append("\n"); //CONTENT-TYPE
            rawDataBuilder.Append(string.Format("{0} GMT", request.Date.ToUniversalTime().ToString("ddd, dd MMM yyyy HH:mm:ss", CultureInfo.GetCultureInfo("en-us")))).Append("\n"); //DATE
            rawDataBuilder.Append("x-mqs-version:").Append(request.Headers["x-mqs-version"]).Append("\n");//CanonicalizedMQSHeaders
            rawDataBuilder.Append(request.RequestUri.LocalPath);

            //Signing with HMACSHA1
            string signature = string.Empty;
            using (var hmacSHA1 = this.GetHashAlgorithm(encoded.GetBytes(accessKeySecret)))
            {
                var hashData = hmacSHA1.ComputeHash(encoded.GetBytes(rawDataBuilder.ToString()));
                signature = Convert.ToBase64String(hashData);
            }

            //Set the authorization of header with acess key and signature.
            request.Headers.Add(HttpRequestHeader.Authorization, string.Format("MQS {0}:{1}", accessKeyID, signature));
        }

        protected virtual System.Security.Cryptography.HashAlgorithm GetHashAlgorithm(byte[] accessKeySecretBytes)
        {
            return new System.Security.Cryptography.HMACSHA1(accessKeySecretBytes);
        }
    }
}
